package com.jackstraw.jack_base.datasource.database.parten.entity;


import com.jackstraw.jack_base.util.entity.BaseEntity;
import lombok.Data;

import java.util.List;

/**
 * 数据库基础连接配置
 *
 * @param <DBE>
 */
@Data
public abstract class DataBaseEntity<DBE extends DataBaseEntity<DBE>> extends BaseEntity<DBE> {

    private final static Integer DEFAULT_INITIAL_SIZE = 0;
    private final static Integer DEFAULT_MAX_ACTIVE_SIZE = 8;
    private final static Integer DEFAULT_MIN_IDLE = 0;
    private final static Long DEFAULT_MAX_WAIT = Long.valueOf(-1);
    private final static String DEFAULT_VALIDATION_QUERY = null;
    private final static Boolean DEFAULT_TEST_ON_BORROW = false;
    private final static Boolean DEFAULT_TEST_ON_RETURN = false;
    private final static Boolean DEFAULT_WHILE_IDLE = true;
    private static final Long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = 60 * 1000L;
    private static final Integer DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
    private static final Long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
    private static final Long DEFAULT_MAX_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 60L * 7;

    /**
     * 连接数据库的用户名
     */
    private String username;
    /**
     * 连接数据库的密码。
     * 如果你不希望密码直接写在配置文件中，可以使用ConfigFilter。
     * 详细看这里: https://github.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter
     */
    private String password;
    /**
     * 连接数据库的url，不同数据库不一样。例如：
     * mysql : jdbc:mysql://10.20.153.104:3306/druid2
     * oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto
     */
    private String jdbcUrl;

    /**
     * 这一项可配可不配，如果不配置druid会根据url自动识别dbType，然后选择相应的driverClassName
     */
    private String driverClass;

    /**
     * 要使用的连接池实现的完全限定名称。 默认情况下，从类路径自动检测它。
     */
    private Class<? extends javax.sql.DataSource> type;

    /**
     * 配置这个属性的意义在于，如果存在多个数据源，监控的时候可以通过名字来区分开来。如果没有配置，将会生成一个名字，格式是："DataSource-" + System.identityHashCode(this).
     * 另外配置此属性至少在1.0.5版本中是不起作用的，强行设置name会出错。
     */
    private String name;

    /**
     * 初始化时建立物理连接的个数。初始化发生在显示调用init方法，或者第一次getConnection时
     */
    private Integer initialSize = DEFAULT_INITIAL_SIZE;
    /**
     * 最大连接池数量
     */
    private Integer maxActive = DEFAULT_MAX_ACTIVE_SIZE;

    /**
     * 最小连接池数量
     */
    private Integer minIdle = DEFAULT_MIN_IDLE;
    /**
     * 获取连接时最大等待时间，单位毫秒。
     * 配置了maxWait之后，缺省启用公平锁，并发效率会有所下降，如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
     */
    private Long maxWait = DEFAULT_MAX_WAIT;
    /**
     * 用来检测连接是否有效的sql，要求是一个查询语句，常用select 'x'。如果validationQuery为null，testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
     */
    private String validationQuery = DEFAULT_VALIDATION_QUERY;
    /**
     * 单位：秒，检测连接是否有效的超时时间。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法
     */
    private Integer validationQueryTimeout = -1;
    /**
     * 申请连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能。
     */
    private Boolean testOnBorrow = DEFAULT_TEST_ON_BORROW;
    /**
     * 归还连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能。
     */
    private Boolean testOnReturn = DEFAULT_TEST_ON_RETURN;
    /**
     * 建议配置为true，不影响性能，并且保证安全性。申请连接的时候检测，如果空闲时间大于timeBetweenEvictionRunsMillis，执行validationQuery检测连接是否有效。
     */
    private Boolean testWhileIdle = DEFAULT_WHILE_IDLE;
    /**
     * 是否缓存preparedStatement，也就是PSCache。
     * PSCache对支持游标的数据库性能提升巨大，比如说oracle。在mysql下建议关闭。
     */
    private Boolean poolPreparedStatements = false;
    /**
     * 要启用PSCache，必须配置大于0，当大于0时，poolPreparedStatements自动触发修改为true。
     * 在Druid中，不会存在Oracle下PSCache占用内存过多的问题，可以把这个数值配置大一些，比如说100
     */
    private Integer maxPoolPreparedStatementPerConnectionSize = -1;

    /**
     * 连接池中的minIdle数量以内的连接，空闲时间超过minEvictableIdleTimeMillis，则会执行keepAlive操作。
     */
    private Boolean keepAlive = Boolean.FALSE;

    /**
     * 有两个含义：
     * 1) Destroy线程会检测连接的间隔时间，如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。
     * 2) testWhileIdle的判断依据，详细看testWhileIdle属性的说明
     */
    private Long timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
    /**
     * 物理连接初始化的时候执行的sql
     */
    private List<String> connectionInitSqls;
    /**
     * 连接保持空闲而不被驱逐的最小时间
     */
    private Long minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    /**
     * 连接保持空闲而不被驱逐的最大时间
     */
    private Long maxEvictableIdleTimeMillis = DEFAULT_MAX_EVICTABLE_IDLE_TIME_MILLIS;

}

